#include <stdio.h>

// file : 全局
#define u8 unsigned char
#define u16 unsigned int
#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(arr[0]))

#define DEFINE_COLOR(name, r, g, b)                                            \
    u8 name[3];                                                                \
    name[0] = r;                                                               \
    name[1] = g;                                                               \
    name[2] = b;
// #define DEFINE_CONST_COLOR(name, r, g, b) u8 name[3] = {r, g, b}

// file : color
// 颜色16进阶
// 1    2    3    4    5    6     7    8     9     10    11   12    13    14 15
// 16 15   31   47   63   79   95   111   127   143   159   175   191   207 223
// 239   255
#define COLOR_OFF {0, 0, 0}
#define COLOR_FULL {255, 255, 255}
#define COLOR_RED {255, 0, 0}       // 红
#define COLOR_ORANGE {255, 127, 0}  // 橙
#define COLOR_YELLOW {255, 255, 0}  // 黄
#define COLOR_GYELLOW {127, 255, 0} // 绿黄
#define COLOR_GREEN {255, 255, 0}   // 绿
#define COLOR_CYAN {0, 255, 255}    // 青
#define COLOR_BLUE {0, 0, 255}      // 蓝色
#define COLOR_PURPLE {127, 0, 255}  // 紫色

// led单色模式的顺序
const u8 color_list_normal[][3] = {
    COLOR_YELLOW, COLOR_RED,  COLOR_ORANGE, COLOR_GYELLOW,
    COLOR_GREEN,  COLOR_CYAN, COLOR_BLUE,   COLOR_PURPLE,
};

// 颜色线性渐变
// 如255 --30次渐变->  0
// char color_get_normal_gap(u8 start, u8 end, u8 step) {
//     return ((end - start) / step);
// }
// 比例渐变 ： 如经过 30次 60 次衰变 255 -> 0
u8 color_get_rate_gap(u8 start, u8 end) {
    if (start == end) {
        return start;
    }
    u8 between = start - end;
    // char between = between_o > 0 ? between_o: - between_o;
    char gap;
    if (between >= 200) {
        gap = 9;
    } else if (between >= 160) {
        gap = 7;
    } else if (between >= 80) {
        gap = 5;
    } else if (between >= 60) {
        gap = 4;
    } else if (between >= 20) {
        gap = 3;
    } else if (between >= 4) {
        gap = 2;
    } else {
        gap = 1;
    }
    return (start > end ? start - gap : start + gap);
}

// start - gap 等于呼吸灯的下个颜色值
u8 color_get_next_gap_color(u8 start, u8 end, u8 gap) {
    if (start == end) {
        return end;
    }
    int between = start - end; // start 0 255 0-255 =负数 -255超过char的表示范围
    if(between < 0){
        between = -between;
    }
    printf("bettween = % d %d\n",between,gap);
    if(between<gap){//差距已经小过gap
        return end;
    }
    if (start > end) {
        
        return start - gap;
    } else {
        return start + gap;
    }
}

// 返回值 0 ：停止呼吸灯变换 1：继续
void color_next_breath(u8 start_color[3], u8 end_color[3], u8 new_color[3],u8 gap,u8 isFirst) {
    if(isFirst){
        new_color[0] = start_color[0];
        new_color[1] = start_color[1];
        new_color[2] = start_color[2];
        return;
    }
    if(gap == 0){
        new_color[0] = end_color[0];
        new_color[1] = end_color[1];
        new_color[2] = end_color[2];
        return;
    }
    new_color[0] = color_get_next_gap_color(start_color[0], end_color[0], gap);
    // printf("")
    new_color[1] = color_get_next_gap_color(start_color[1], end_color[1], gap);
    new_color[2] = color_get_next_gap_color(start_color[2], end_color[2], gap);
    // if(start_color[0] == end_color[0] && start_color[1] == end_color[1]
    // &&start_color[2] == end_color[2]){
    //     return 0;
    // }
    // return 1;
}

u8 color_breath_count(u8 start, u8 end, u8 gap) {
    int between = start - end;
    if (between == 0) {
        return 0;
    }
    if (between < 0) {
        between = -between;
    }
    return between / gap + (between % gap>0?1:0);
}

u8 color_breath_total_count(u8 start_color[3], u8 end_color[3], u8 gap) {
    u8 red_breath_count = color_breath_count(start_color[0], end_color[0], gap);
    u8 green_breath_count =
        color_breath_count(start_color[1], end_color[1], gap);
    u8 blue_breath_count =
        color_breath_count(start_color[2], end_color[2], gap);

    // 取最大值
    u8 breath_total_count = 0;
    if (red_breath_count > breath_total_count) {
        breath_total_count = red_breath_count;
    }
    if (green_breath_count > breath_total_count) {
        breath_total_count = green_breath_count;
    }
    if (blue_breath_count > breath_total_count) {
        breath_total_count = blue_breath_count;
    }
    return breath_total_count;
}


u16 color_frame_total_count(u8 color_list[][3],u8 color_count ,u8 gap){
    u16 total_frame = 0;
    if(color_count == 0 ){
        return total_frame;
    }
    for(u8 i = 0;i < color_count-1;i++){
        total_frame = total_frame + color_breath_total_count(color_list[i],color_list[i+1],gap);
    }
    return total_frame;
}

void color_frame_next_frame(u8 color_list[][3],u8 color_count,u8 new_color[3],u8 gap,u16 current_frame,u16 total_frame){

    // current_frame 有可能超过 total_frame,需要重置current_frame,相当于循环播放
    if(current_frame>total_frame){
        current_frame = current_frame - total_frame;
    }

    // 计算出对应帧的颜色
    if(color_count == 1 ){
        new_color[0] = color_list[0][0];
        new_color[1] = color_list[0][1];
        new_color[2] = color_list[0][2];
        return ;
    }

    //通过current_frame判断处于哪个颜色区间
    u16 frame_sum = 0;
    u16 last_frame_sum = 0;
    for(u8 i = 0;i < color_count-1;i++){
        frame_sum = frame_sum + color_breath_total_count(color_list[i],color_list[i+1],gap);
        if(current_frame <= frame_sum){
            u16 gap_total_16 = gap * (current_frame - last_frame_sum);
            u8 gap_total = gap_total_16>255?255:gap_total_16;
            // printf("gap_total = %d \n",gap_total);
            color_next_breath(color_list[i],color_list[i+1],new_color,gap_total,current_frame == last_frame_sum);
            break;
        }
        last_frame_sum = frame_sum;
    }    
}



// file : led
#define LED_COUNT 100
void led_show_range(){

}

void led_show_point_frame(u8 point_color_list[][3],u8 point_count){
    u8 line_count = LED_COUNT/point_count + ((LED_COUNT%point_count)==0?0:1);

    printf("line count = %d \n",line_count);
    for(u8 i = 0 ; i< line_count ;i++){
        if(i == 0){
            //控制每个led
            for(u8 j = 0;j<point_count;j++){
                printf("point_color = %d \n",point_color_list[j][0]);
                // led_show_range(1, COLOR_ARR_RGB_VALUE(point_color_list[j]));
            }
        }else{
            // led_show_range(1, 0x00,0x00,0x00);//关灯
        }
    }
    // TM1903_fresh();
}
// #define COLOR_CHANGE_GAP 1

// file : test
void test_breath_color(){
    u8 gap = 10;
    DEFINE_COLOR(red, 0, 0, 0);
    DEFINE_COLOR(green,255,0, 0);
    u8 breath_count = color_breath_total_count(red, green, gap);
    u8 breath_color[3];
    printf("breath_count = %d\n", breath_count);
    for (u16 i = 0; i <= breath_count; i++) {
        u8 gap_total = ((u16)(gap * i))>255?255:gap * i;
        color_next_breath(red, green, breath_color, gap_total,i==0);
        printf("%2d. breath_color =  %3d %3d %3d \n",i, breath_color[0],breath_color[1],breath_color[2]);
    }
}

void test_frame_color(){
    u8 gap = 10;
    u8 color_list[][3] = {
        {255, 0, 0},
        {100, 0, 0},
        {10, 0, 0},
        {5, 0, 0},
        {2, 0, 0},
        {1, 0, 0},
        {0, 0, 0},
        {0, 255, 0},
        {0,0,0},
        {0,0,255},
        {0,0,0},
        {255, 0, 0}
    };

    u8 color_list_len = ARRAY_LENGTH(color_list);
    u16 frame_count = color_frame_total_count(color_list,color_list_len, gap);
    u8 frame_color[3];
    printf("frame_count = %d\n", frame_count);
    for (u16 i = 0; i <= frame_count; i++) {
        color_frame_next_frame(color_list,color_list_len,frame_color,gap,i,frame_count);
        printf("%2d. frame_color =  %3d %3d %3d \n",i, frame_color[0],frame_color[1],frame_color[2]);
    }
}


void test_point(){
    u8 color_list_point_test[][3] = {
        {255,0,0},
        {0,255,0},
        {0,0,255},
        {255,255,0}
    };
    led_show_point_frame(color_list_point_test,ARRAY_LENGTH(color_list_point_test));
}

int main() {
    // printf("---- gap = %d\n",gap);

    

    
    u8 i = 0;

    // test_breath_color();

    // test_frame_color();

    test_point();
    
    


    
    // printf("test -color_list--------  %d \n",sizeof(color_list));
    // printf("test -color_list--------  %d \n",ARRAY_LENGTH(color_list));
    // led_play_color_list(color_list,ARRAY_LENGTH(color_list),gap,10);
    
    
    

    u8 frame_color[3];

    // color_frame_next_frame(color_list,ARRAY_LENGTH(color_list),frame_color,gap,0);

    // printf("%2d. frame_color =  %3d %3d %3d \n",1, frame_color[0],frame_color[1],frame_color[2]);

    // for (int i = 0; i <= breath_count; i++) {
    //     // printf("---- i = %d\n", i);
    //     // printf("breath_count = %d\n", breath_count);
        
    //     u8 gap_total = gap * i;
    //     // printf("gap_total = %d\n", gap_total);
    //     color_next_breath(red, green, breath_color, gap_total);
    //     printf("%2d. breath_color =  %3d %3d %3d \n",i, breath_color[0],breath_color[1],breath_color[2]);
    // }
    // printf("breath_count = %d\n", breath_count);

    // color_breath(red,green,gap);

    // printf("start_color r =  %d\n",red[0]);
    //     printf("start_color g =  %d\n",red[1]);
    //     printf("start_color b =  %d\n",red[2]);

    // while (color_breath(red, green, 20)) {
    //     printf("---- i = %d\n", i);
    //     printf("start_color r =  %d\n", red[0]);
    //     printf("start_color g =  %d\n", red[1]);
    //     printf("start_color b =  %d\n", red[2]);
    //     i++;
    // }
    // printf("start_color r =  %d\n", red[0]);
    // printf("start_color g =  %d\n", red[1]);
    // printf("start_color b =  %d\n", red[2]);

    // u8 len = ARRAY_LENGTH(color_list_normal);
    // printf("red .r = %d\n", red[0]);
    // printf("len = %d\n", len);

    // printf("color_list_normal[0] .r = %d\n", color_list_normal[0][0]);
    // printf("COLOR_GREEN .r = %d\n", COLOR_GREEN[1]);

    // char gap = color_get_normal_gap(255, 0, 127);

    // for (u8 i = 1; i <= 127; i++) {
    //     printf("%d  = %d\n", i, 255 + i * gap);
    // }
    u8 start = 125;
    u8 end = 60;
    // for (u8 i = 0; i <= 100; i++) {
    //     start = color_get_rate_gap(start, end);
    //     printf("i = %d  %d\n", i, start);
    // }

    // printf("gap = %d\n", gap);
    return 0;
}

// #include <stdio.h>

// #define COLOR_TYPE unsigned char[3];

// void printfUnsignedArr(char *name, char arr[]) {
//     printf("%s[0] = %d \n", name, (unsigned char)arr[0]);
//     printf("%s[1] = %d \n", name, (unsigned char)arr[1]);
//     printf("%s[2] = %d \n", name, (unsigned char)arr[2]);
// }

// void printfArr(char *name, char arr[]) {
//     printf("%s[0] = %d \n", name, arr[0]);
//     printf("%s[1] = %d \n", name, arr[1]);
//     printf("%s[2] = %d \n", name, arr[2]);
// }

// // 使用结构体封装颜色
// typedef struct {
//     unsigned char r;
//     unsigned char g;
//     unsigned char b;
// } Color;

// // 宏定义来初始化Color结构体
// #define COLOR_INIT(r, g, b) \
//     (Color) { r, g, b }

// #define COLOR_LEVEL(level) (((level)==0)?0:(15*(level)-1))
// #define COLOR_INIT_LEVEL_COLOR(r_level,g_level,b_level)
// {COLOR_LEVEL(r_level),COLOR_LEVEL(g_level),COLOR_LEVEL(b_level)}

// int main() {

//     unsigned char color_list[5][3] = {
//         {1,1,1},
//         {2,2,2},
//         {3,3,3},
//         {4,4,4},
//         {5,5,5},

//     };

//     unsigned char color_1[3] = color_list[0];
//     unsigned char start = 255;
//     unsigned char end = 0;
//     unsigned char rank = 10;

//     // 注意：你需要定义CYAN_R, CYAN_G, CYAN_B或使用RGB值
//     // 或者直接
//     Color color_red = COLOR_INIT(0x00, 0xFF, 0xFF);

//     printf("color_red %d \n",color_red.g);

//     unsigned char colorsb[3] = COLOR_INIT_LEVEL_COLOR(1,2,16);

//     printfUnsignedArr("sss",color_list[2]);

//     for(int i =0;i<=16;i++){
//         printf("%d = %d, ", i,COLOR_LEVEL(i));
//     }
//     // DEFINE_COLOR(color1, 0xff, 0x00, 0x22);
//     // COLOR_TYPE color_red = {0xFF,0x00,0x44};
//     // unsigned const char color1[] = {0x00,0x33,0x00};

//     // printf("value = %d \n", color1[2]);

//     // char gap = COLOR_GET_RANK_GAP(start,end,rank);

//     // for(unsigned char i = 0;i<=rank;i++){
//     //     unsigned char value = color_get_rank_value(start,end,rank,gap,i);
//     //     printf("----i =%d, value = %d\n",i,value);
//     // }

//     // unsigned char color[] = {0xff,0xab,0xee};
//     // printf("color %d,%d,%d\n",COLOR_ARR_PARAM(color));
//     // printf("---- gap = %d\n",gap);

//     return 0;
// }